<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>23_Vue-数组更新的检测</title>
  <!-- 
  在 Vue 中，数组的更新检测是响应式系统的重要部分。Vue 提供了一些方法来确保对数组的更改能够被检测到并触发视图更新。
  1. 响应式数组
  Vue 通过  `Object.defineProperty`  或 Proxy（在 Vue 3 中）来实现响应式数据。因此，Vue 能够监测到数组的变化，并在变化时自动更新视图。

  2. 数组变更的检测
  在 Vue 中，数组的变更检测主要依赖以下几种方法：
   2.1 通过数组方法
  Vue 会自动检测以下数组方法的调用：

  -  `push()` 
  -  `pop()` 
  -  `shift()` 
  -  `unshift()` 
  -  `splice()` 
  -  `sort()` 
  -  `reverse()` 

  这些方法会触发视图的更新，因为它们会改变数组的内容。

  3. 直接赋值的方式
  如果直接通过索引赋值来更新数组，例如  `this.array[index] = newValue` ，Vue 不能检测到这种变化。为了确保视图更新，可以使用  `Vue.set()`  或  `this.$set()`  方法：
  this.$set(this.array, index, newValue);
  4. 使用  `splice()`  方法

  对于数组的插入和删除操作，推荐使用  `splice()`  方法，因为它会触发视图更新。例如：
  this.array.splice(index, 1); // 删除元素
  this.array.splice(index, 0, newValue); // 插入新元素

  5. Vue 3 中的 Proxy
  在 Vue 3 中，响应式系统使用 Proxy 来实现更好的性能和更强的功能。Proxy 能够捕捉到对数组的所有操作，包括直接赋值，因此在 Vue 3 中，直接通过索引赋值也会触发视图更新。

  6. 总结
  - 响应式系统：Vue 通过响应式系统监测数组的变化。
  - 自动检测的方法： `push()` 、 `pop()` 、 `shift()` 、 `unshift()` 、 `splice()` 、 `sort()` 、 `reverse()`  等方法会触发视图更新。
  - 直接赋值：直接通过索引赋值不会触发更新，使用  `Vue.set()`  或  `this.$set()`  来更新。
  - Vue 3 的改进：Vue 3 使用 Proxy 使得直接赋值也能够触发更新。
  -->
</head>
<body>

  <div id="app">
    <ul>
      <li v-for="item in items" :key="item">{{ item }}</li>
    </ul>
    <button @click="updateArray">更新数组</button>
  </div>
  <script src="../lib/vue.js"></script>
  <script>
    const { createApp, ref } = Vue

    createApp({
      setup() {
        const items = ref(['a', 'b', 'c', 'd'])

        const updateArray = () => {
          // 1.直接将数组修改为一个新的数组
          // items.value = ["array", "update", "arrayFn", "updateFn"]

          // 2.通过一些数组的方法, 修改数组中的元素
          // items.value.push("newArray")
          // items.value.pop()
          // items.value.splice(2, 1, "newArray")
          // items.value.sort()
          // items.value.reverse()

          // 3.不修改原数组的方法是不能侦听(watch)
          items.value = items.value.map(item => item + "new")
        }

        return {
          items,
          updateArray
        }
      }
    }).mount('#app')

  </script>
   
  
</body>
</html>